import numpy as np
import csv
import random
from datetime import datetime
from time import strftime
import itertools as itertools
import math as math

'''
revision of test25 for Mar21
to calculate the false nagetive, false positive

'''

def getCurTime():
    """
    get current time
    Return value of the date string format(%Y-%m-%d %H:%M:%S)
    """
    format='%Y-%m-%d %H:%M:%S'
    sdate = None
    cdate = datetime.now()
    try:
        sdate = cdate.strftime(format)
    except:
        raise ValueError
    return sdate

def build_unit_list(inputCSV):
    sKey = np.array([])
    fn = inputCSV
    ra = csv.DictReader(file(fn), dialect="excel")
    i = 0
    for record in ra:
        #print record[ra.fieldnames[0]], type(record[ra.fieldnames[-1]])
        temp = [int(float(record["GIST_ID"])), int(float(record[cancerFN])),int(float(record[popFN])), 0]
        sKey =np.append(sKey, temp)
        i += 1
    sKey.shape=(-1,4)
    return sKey

def build_region_list(inputCSV):
    fn = inputCSV
    ra = csv.DictReader(file(fn), dialect="excel")
    temp_list = np.array([])
    i = 0
    for record in ra:
        #print record[ra.fieldnames[0]], type(record[ra.fieldnames[-1]])
        temp_list = np.append(temp_list, [int(float(record[ra.fieldnames[0]])), int(float(record[ra.fieldnames[-1]]))])
        #unit_attri[i,3] = int(float(record[ra.fieldnames[-1]]))
        i = i + 1
    temp_list.shape = (-1,2)
    return temp_list
        
def poisson_likelihood_ratio(iObZ, iObT, iPopZ, iPopT):
    # iObZ: the observed number in the certain Zone, e.g. the number of cancer cases in a region
    # iObT: the total observed number, e.g. the total number of cancer cases
    # iPopZ: the population in the certain Zone 
    # iPopT: the total population
    temp_lambda = 0.0
    temp_z_p = (0.0 + iObZ)/iPopZ
    temp_out_p = (0.0 + iObT - iObZ)/(iPopT - iPopZ)
    temp_t_p = (0.0 + iObT)/iPopT
    if temp_z_p > temp_out_p:
        #temp_denominator = temp_t_p ** int(iObT)
        #temp_numerator = (temp_z_p**int(iObZ))*(temp_out_p**int(iObT - iObZ))
        #temp_lambda = temp_numerator/temp_denominator
        temp = iObZ * math.log(temp_z_p) + (iObT - iObZ)* math.log(temp_out_p) - iObT * math.log(temp_t_p)
    return temp_lambda

# unit_attri: [id, cancer, pop, region_id]
def poisson_region_likelihood_ratio(t_region_attri, temp_total_caner, temp_total_pop):
    # t_region_attri: the attribution (id, cancer, pop, region_id) of the region of interest
    # temp_total_caner
    # temp_total_pop
    iLen = t_region_attri.shape
    temp_ratio = np.array([])
    for i in range(1, (iLen[0]+1)):
        temp_id = itertools.combinations(range(iLen[0]), i)
        for item in temp_id:
            temp_sub_region = np.array([])
            for temp_temp_id in item:
                temp_sub_region = np.append(temp_sub_region, t_region_attri[temp_temp_id])
            temp_sub_region.shape = (-1, 4)
            temp_caner = np.sum(temp_sub_region[:,1])
            temp_pop = np.sum(temp_sub_region[:,2])
            temp_ratio = np.append(temp_ratio, poisson_likelihood_ratio(temp_caner, temp_total_caner, temp_pop, temp_total_pop))
    try:
        temp_likelihood_ratio = np.max(temp_ratio)
    except:
        raise ValueError
    if temp_likelihood_ratio == 0.0:
        temp_likelihood_ratio = 1
    return temp_likelihood_ratio

def find_region(t_unit_attri, id):
    # find the unit attribution of region_id ="id"
    t_region = np.array([])
    for item in t_unit_attri:
        if int(item[3]) == id:
            t_region = np.append(t_region, item)
            '''
            try:
                t_region = np.append(t_region, item)
            except:
                raise ValueError
            '''
    iLen = t_unit_attri.shape
    t_region.shape = (-1, iLen[1])
    return t_region

def poisson_whole_likelihood_ratio(t_unit_attri, temp_total_caner, temp_total_pop):
    # t_unit_attri: the attribution (id, cancer, pop, region_id) of the whole study area
    # t_region_attri: region id for each unit
    region_id = np.unique(t_unit_attri[:,3])
    temp_likelihood_ratio = np.array([])
    '''
    i = 131
    t_region_attri = find_region(t_unit_attri, i)
    temp_likelihood_ratio = np.append(temp_likelihood_ratio, poisson_region_likelihood_ratio(t_region_attri, temp_total_caner, temp_total_pop))

    '''
    for i in region_id:
        t_region_attri = find_region(t_unit_attri, i)
        temp_likelihood_ratio = np.append(temp_likelihood_ratio, poisson_region_likelihood_ratio(t_region_attri, temp_total_caner, temp_total_pop))
        print i
    
    return temp_likelihood_ratio


def build_contiguity_list(CongtiguityFC):
    spContiguity = np.array([],dtype=int)
    #read contiguity file
    fn = CongtiguityFC
       
    for record in csv.DictReader(file(fn), dialect="excel"):
        temp = [int(float(record[ra.fieldnames[0]])), int(float(record[ra.fieldnames[-1]]))]
        spContiguity=np.append(spContiguity, temp)
    spContiguity.shape=(-1,2)
    return spContiguity

def contiguity_item(ID, ID_2 t_region_attri):
    contiguityItem = np.array([])
    for item in spContiguity:
        if item[0] <> item[1]:
            if item[0] == ID && item[1] > ID_2:
                contiguityItem = np.append(contiguityItem, item[1])
    return contiguityItem

def sp_combinations(t_region_attri, r):
    # t_region_attri: [id, caner, pop, region_id]
    unit_id = np.argsort(t_region_attri[:,0])
    pool = np.array([])
    for i in unit_id:
        temp = np.array([])
        temp = np.append(temp, i)
        contiguityItem = contiguity_item(ID, t_region_attri)
        
    


#--------------------------------------------------------------------------
#MAIN

if __name__ == "__main__":
    print "begin at " + getCurTime()

    filePath = "C:/_DATA/CancerData/"
    unitCSV = "C:/_DATA/CancerData/LATrtCancerS.csv"
    regionCSV = "C:/_DATA/CancerData/test/Apr1_real_data/2_CLK_SO_POP_min_20000_157reg.csv"
    popFN = "POP_2000"
    # COUNT02    COUNT03    COUNT04    COUNT05    COUNT06    COUNT02_06
    cancerFN = "COUNT02"
    unit_attri = build_unit_list(unitCSV)  # [id, cancer, pop, region_id]
    total_caner = np.sum(unit_attri[:,1])
    total_pop = np.sum(unit_attri[:,2])
    region_id = build_region_list(regionCSV)
    
    i = 0
    for unit in unit_attri:
        for region in region_id:
            if int(unit[0]) == int(region[0]):
                unit[3] = region[1]
                break

    contituigy_csv = "C:/_DATA/CancerData/NCTrtCancer_ROOK_re_contiguity.csv"
    spContiguity = build_contiguity_list(contituigy_csv)
    likelihood_ratio = poisson_whole_likelihood_ratio(unit_attri, total_caner, total_pop)
    print likelihood_ratio
    np.savetxt("C:/likelihood_ratio.csv", likelihood_ratio, delimiter=',')


    print "end at " + getCurTime()
    print "========================================================================"  